/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * SicknessReportEditor.java
 *
 * Created on 19-Jun-2010, 00:28:18
 */

package TimeRecording.forms;

import TimeRecording.business.DaisyChainSystem;
import TimeRecording.business.DaisyChainUtilities;
import TimeRecording.business.SicknessCalculations;
import TimeRecording.business.SpendExplanation;
import TimeRecording.enums.PartOfDay;
import TimeRecording.enums.SicknessReportStatus;
import TimeRecording.tables.SicknessReport;
import TimeRecording.widgets.EmployeeComboBox;
import TimeRecording.widgets.PartOfDayComboBox;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JOptionPane;
import org.jdesktop.application.Action;

/**
 *
 * @author david
 */
public class SicknessReportEditor extends javax.swing.JDialog implements PropertyChangeListener {

    /** Creates new form SicknessReportEditor */
    public SicknessReportEditor(SicknessReportDialog parent) {
        super(parent, ModalityType.APPLICATION_MODAL);
        myParent = parent;
        initComponents();
    }

    private SicknessCalculations sicknessCalculations = new SicknessCalculations();
    private SpendExplanation explanation = new SpendExplanation();

    // <editor-fold defaultstate="collapsed" desc="Property Change Support">
    private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);

    @Override
    public void addPropertyChangeListener(PropertyChangeListener listener) {
	changeSupport.addPropertyChangeListener(listener);
    }

    @Override
    public void removePropertyChangeListener(PropertyChangeListener listener) {
	changeSupport.removePropertyChangeListener(listener);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="transientSickness + Getter + Setter">
    private SicknessReport transientSickness = new SicknessReport();

    public SicknessReport getTransientSickness() {
        return transientSickness;
    }

    public void setTransientSickness(SicknessReport transientSickness) {
        SicknessReport oldTransientSickness = this.transientSickness;
        this.transientSickness = transientSickness;
        changeSupport.firePropertyChange("transientSickness", oldTransientSickness, transientSickness);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="persistentSickness + Getter + Setter">
    private SicknessReport persistentSickness;

    public SicknessReport getPersistentSickness() {
        return persistentSickness;
    }

    public void setPersistentSickness(SicknessReport persistentSickness) {
        SicknessReport oldPersistentSickness = this.persistentSickness;
        this.persistentSickness = persistentSickness;
        changeSupport.firePropertyChange("persistentSickness", oldPersistentSickness, persistentSickness);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="administratorLoggedIn + Getter + Setter">
    private boolean administratorLoggedIn;
    
    public boolean isAdministratorLoggedIn() {
        return administratorLoggedIn;
    }
    
    public void setAdministratorLoggedIn(boolean administratorLoggedIn) {
        boolean oldAdministratorLoggedIn = this.administratorLoggedIn;
        this.administratorLoggedIn = administratorLoggedIn;
        changeSupport.firePropertyChange("administratorLoggedIn", oldAdministratorLoggedIn, administratorLoggedIn);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="administratorEditable + Getter + Setter">
    private boolean administratorEditable = false;

    public boolean isAdministratorEditable() {
        return administratorEditable;
    }

    public void setAdministratorEditable(boolean administratorEditable) {
        boolean oldAdministratorEditable = this.administratorEditable;
        this.administratorEditable = administratorEditable;
        changeSupport.firePropertyChange("administratorEditable", oldAdministratorEditable, administratorEditable);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="notYetSubmitted + Getter + Setter">
    private boolean notYetSubmitted;

    public boolean isNotYetSubmitted() {
        return notYetSubmitted;
    }

    public void setNotYetSubmitted(boolean notYetSubmitted) {
        boolean oldNotYetSubmitted = this.notYetSubmitted;
        this.notYetSubmitted = notYetSubmitted;
        changeSupport.firePropertyChange("notYetSubmitted", oldNotYetSubmitted, notYetSubmitted);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="notYetProcessed + Getter + Setter">
    private boolean notYetProcessed;

    public boolean isNotYetProcessed() {
        return notYetProcessed;
    }

    public void setNotYetProcessed(boolean notYetProcessed) {
        boolean oldNotYetProcessed = this.notYetProcessed;
        this.notYetProcessed = notYetProcessed;
        changeSupport.firePropertyChange("notYetProcessed", oldNotYetProcessed, notYetProcessed);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SaveSelected + Getter + Setter">
    private boolean saveSelected;

    public boolean isSaveSelected() {
        return saveSelected;
    }

    public void setSaveSelected(boolean saveSelected) {
        boolean oldSaveSelected = this.saveSelected;
        this.saveSelected = saveSelected;
        changeSupport.firePropertyChange("saveSelected", oldSaveSelected, saveSelected);
    } // </editor-fold>

    public void setSickness(SicknessReport sickness) {
        
        setPersistentSickness(sickness);
        
        transientSickness.copy(sickness);
        transientSickness.addPropertyChangeListener(this);

        setNotYetSubmitted(sickness.getStatus() == SicknessReportStatus.PREPARATION);

        setNotYetProcessed(sickness.getStatus() != SicknessReportStatus.PROCESSED);

        setAdministratorEditable(isAdministratorLoggedIn() && isNotYetSubmitted());
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        entityManager = myParent.getEntityManager();
        dateConverter = new TimeRecording.widgets.DateConverter();
        sicknessReportStatusConverter = new TimeRecording.enums.SicknessReportStatusConverter();
        sicknessReportDetails = new javax.swing.JPanel();
        employeeLabel = new javax.swing.JLabel();
        employee = new EmployeeComboBox(entityManager);
        administratorLabel = new javax.swing.JLabel();
        administrator = new javax.swing.JTextField();
        employeeCommentLabel = new javax.swing.JLabel();
        employeeComment = new javax.swing.JTextField();
        administratorCommentLabel = new javax.swing.JLabel();
        administratorComment = new javax.swing.JTextField();
        fromLabel = new javax.swing.JLabel();
        fromDate = new com.toedter.calendar.JDateChooser();
        firstDayPartCombo = new PartOfDayComboBox();
        toLabel = new javax.swing.JLabel();
        toDate = new com.toedter.calendar.JDateChooser();
        lastDayPartCombo = new PartOfDayComboBox();
        hoursLostLabel = new javax.swing.JLabel();
        hoursLost = new javax.swing.JFormattedTextField();
        explainButton = new javax.swing.JButton();
        statusLabel = new javax.swing.JLabel();
        status = new javax.swing.JTextField();
        fromFlexiCheck = new javax.swing.JCheckBox();
        buttonPanel = new javax.swing.JPanel();
        saveButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(TimeRecording.TimeRecordingApp.class).getContext().getResourceMap(SicknessReportEditor.class);
        setTitle(resourceMap.getString("Form.title")); // NOI18N
        setName("Form"); // NOI18N
        getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.PAGE_AXIS));

        sicknessReportDetails.setBorder(javax.swing.BorderFactory.createEmptyBorder(4, 8, 4, 8));
        sicknessReportDetails.setName("sicknessReportDetails"); // NOI18N
        sicknessReportDetails.setLayout(new java.awt.GridBagLayout());

        employeeLabel.setText(resourceMap.getString("employeeLabel.text")); // NOI18N
        employeeLabel.setName("employeeLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 4);
        sicknessReportDetails.add(employeeLabel, gridBagConstraints);

        employee.setName("employee"); // NOI18N

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.employeeId}"), employee, org.jdesktop.beansbinding.BeanProperty.create("selectedItem"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${administratorEditable}"), employee, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 8);
        sicknessReportDetails.add(employee, gridBagConstraints);

        administratorLabel.setText(resourceMap.getString("administratorLabel.text")); // NOI18N
        administratorLabel.setName("administratorLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 8);
        sicknessReportDetails.add(administratorLabel, gridBagConstraints);

        administrator.setEditable(false);
        administrator.setName("administrator"); // NOI18N

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.administratorId.friendlyName}"), administrator, org.jdesktop.beansbinding.BeanProperty.create("text"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 50.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 4);
        sicknessReportDetails.add(administrator, gridBagConstraints);

        employeeCommentLabel.setText(resourceMap.getString("employeeCommentLabel.text")); // NOI18N
        employeeCommentLabel.setName("employeeCommentLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 4);
        sicknessReportDetails.add(employeeCommentLabel, gridBagConstraints);

        employeeComment.setName("employeeComment"); // NOI18N

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.employeeComment}"), employeeComment, org.jdesktop.beansbinding.BeanProperty.create("text"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${notYetSubmitted}"), employeeComment, org.jdesktop.beansbinding.BeanProperty.create("editable"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 100.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        sicknessReportDetails.add(employeeComment, gridBagConstraints);

        administratorCommentLabel.setText(resourceMap.getString("administratorCommentLabel.text")); // NOI18N
        administratorCommentLabel.setName("administratorCommentLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 4);
        sicknessReportDetails.add(administratorCommentLabel, gridBagConstraints);

        administratorComment.setName("administratorComment"); // NOI18N

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.administratorComment}"), administratorComment, org.jdesktop.beansbinding.BeanProperty.create("text"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${administratorLoggedIn}"), administratorComment, org.jdesktop.beansbinding.BeanProperty.create("editable"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 100.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        sicknessReportDetails.add(administratorComment, gridBagConstraints);

        fromLabel.setText(resourceMap.getString("fromLabel.text")); // NOI18N
        fromLabel.setName("fromLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 4);
        sicknessReportDetails.add(fromLabel, gridBagConstraints);

        fromDate.setMinimumSize(new java.awt.Dimension(150, 20));
        fromDate.setName("fromDate"); // NOI18N
        fromDate.setPreferredSize(new java.awt.Dimension(120, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.firstDayOfSickness}"), fromDate, org.jdesktop.beansbinding.BeanProperty.create("date"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${notYetSubmitted}"), fromDate, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        fromDate.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                fromDatePropertyChange(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 50.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        sicknessReportDetails.add(fromDate, gridBagConstraints);

        firstDayPartCombo.setMinimumSize(new java.awt.Dimension(90, 18));
        firstDayPartCombo.setName("firstDayPartCombo"); // NOI18N
        firstDayPartCombo.setPreferredSize(new java.awt.Dimension(90, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.firstDayPart}"), firstDayPartCombo, org.jdesktop.beansbinding.BeanProperty.create("selectedItem"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${notYetSubmitted}"), firstDayPartCombo, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        sicknessReportDetails.add(firstDayPartCombo, gridBagConstraints);

        toLabel.setText(resourceMap.getString("toLabel.text")); // NOI18N
        toLabel.setName("toLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 8, 4);
        sicknessReportDetails.add(toLabel, gridBagConstraints);

        toDate.setMinimumSize(new java.awt.Dimension(150, 20));
        toDate.setName("toDate"); // NOI18N
        toDate.setPreferredSize(new java.awt.Dimension(120, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.lastDayOfSickness}"), toDate, org.jdesktop.beansbinding.BeanProperty.create("date"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${notYetSubmitted}"), toDate, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 50.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 8, 4);
        sicknessReportDetails.add(toDate, gridBagConstraints);

        lastDayPartCombo.setMinimumSize(new java.awt.Dimension(90, 18));
        lastDayPartCombo.setName("lastDayPartCombo"); // NOI18N
        lastDayPartCombo.setPreferredSize(new java.awt.Dimension(90, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.lastDayPart}"), lastDayPartCombo, org.jdesktop.beansbinding.BeanProperty.create("selectedItem"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${notYetSubmitted}"), lastDayPartCombo, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 8, 4);
        sicknessReportDetails.add(lastDayPartCombo, gridBagConstraints);

        hoursLostLabel.setText(resourceMap.getString("hoursLostLabel.text")); // NOI18N
        hoursLostLabel.setName("hoursLostLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 12, 4, 4);
        sicknessReportDetails.add(hoursLostLabel, gridBagConstraints);

        hoursLost.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0.00"))));
        hoursLost.setText(resourceMap.getString("hoursLost.text")); // NOI18N
        hoursLost.setName("hoursLost"); // NOI18N

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.hoursLost}"), hoursLost, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${administratorEditable}"), hoursLost, org.jdesktop.beansbinding.BeanProperty.create("editable"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        sicknessReportDetails.add(hoursLost, gridBagConstraints);

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(TimeRecording.TimeRecordingApp.class).getContext().getActionMap(SicknessReportEditor.class, this);
        explainButton.setAction(actionMap.get("explainClicked")); // NOI18N
        explainButton.setText(resourceMap.getString("explainButton.text")); // NOI18N
        explainButton.setMaximumSize(new java.awt.Dimension(140, 23));
        explainButton.setMinimumSize(new java.awt.Dimension(140, 23));
        explainButton.setName("explainButton"); // NOI18N
        explainButton.setPreferredSize(new java.awt.Dimension(140, 20));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        sicknessReportDetails.add(explainButton, gridBagConstraints);

        statusLabel.setText(resourceMap.getString("statusLabel.text")); // NOI18N
        statusLabel.setName("statusLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 12, 8, 4);
        sicknessReportDetails.add(statusLabel, gridBagConstraints);

        status.setEditable(false);
        status.setName("status"); // NOI18N
        status.setPreferredSize(new java.awt.Dimension(120, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.status}"), status, org.jdesktop.beansbinding.BeanProperty.create("text"));
        binding.setConverter(sicknessReportStatusConverter);
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 50.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 8, 4);
        sicknessReportDetails.add(status, gridBagConstraints);

        fromFlexiCheck.setText(resourceMap.getString("fromFlexiCheck.text")); // NOI18N
        fromFlexiCheck.setName("fromFlexiCheck"); // NOI18N

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${transientSickness.takenFromFlexi}"), fromFlexiCheck, org.jdesktop.beansbinding.BeanProperty.create("selected"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${notYetSubmitted}"), fromFlexiCheck, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        sicknessReportDetails.add(fromFlexiCheck, gridBagConstraints);

        buttonPanel.setName("buttonPanel"); // NOI18N

        saveButton.setAction(actionMap.get("saveClicked")); // NOI18N
        saveButton.setText(resourceMap.getString("saveButton.text")); // NOI18N
        saveButton.setName("saveButton"); // NOI18N
        buttonPanel.add(saveButton);

        cancelButton.setAction(actionMap.get("cancelClicked")); // NOI18N
        cancelButton.setText(resourceMap.getString("cancelButton.text")); // NOI18N
        cancelButton.setName("cancelButton"); // NOI18N
        buttonPanel.add(cancelButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = 6;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        sicknessReportDetails.add(buttonPanel, gridBagConstraints);

        getContentPane().add(sicknessReportDetails);

        bindingGroup.bind();

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-875)/2, (screenSize.height-239)/2, 875, 239);
    }// </editor-fold>//GEN-END:initComponents

    private void fromDatePropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_fromDatePropertyChange
        if (toDate.getDate() == null) {
            toDate.setDate(fromDate.getDate());
        }
    }//GEN-LAST:event_fromDatePropertyChange

    private boolean validateSicknessReport() {
        
        if (transientSickness.getEmployeeId() == null ||
                transientSickness.getFirstDayOfSickness() == null ||
                transientSickness.getFirstDayPart() == null ||
                transientSickness.getHoursLost() == null) {

            JOptionPane.showMessageDialog(this,
                    "Insufficient details supplied",
                    "Save Sickness Report",
                    JOptionPane.ERROR_MESSAGE);

            return false;
        }

        boolean oneDayOrLess = false;
        boolean negativeSpan = false;

        if (transientSickness.getLastDayOfSickness() != null &&
                transientSickness.getLastDayPart() != null) {

            oneDayOrLess =
                    DaisyChainSystem.cleanDate(transientSickness.getFirstDayOfSickness()).getTime() ==
                    DaisyChainSystem.cleanDate(transientSickness.getLastDayOfSickness()).getTime();

            negativeSpan =
                    DaisyChainSystem.cleanDate(transientSickness.getFirstDayOfSickness()).getTime() >
                    DaisyChainSystem.cleanDate(transientSickness.getLastDayOfSickness()).getTime();

        }

        // Does the sickness report start and finish on the same day?

        if (oneDayOrLess) {

            // Do the start and end part combo boxes look inconsistent?

            if (transientSickness.getFirstDayPart() !=
                    transientSickness.getLastDayPart()) {

                // Does it look like a single full day?  If so then we can
                // modify the combo values and ask the user to re-save.

                boolean probableFullDay = false;

                // AM start, PM finish? Probably a full day is the intention

                if (transientSickness.getFirstDayPart() == PartOfDay.AM &&
                        transientSickness.getLastDayPart() == PartOfDay.PM) {
                    probableFullDay = true;
                }

                // AM start, full day finish?  Probably a full day is the intention

                if (transientSickness.getFirstDayPart() == PartOfDay.AM &&
                        transientSickness.getLastDayPart() == PartOfDay.ALL_DAY) {
                    probableFullDay = true;
                }

                // Full day start, PM finish?  Probably a full day is the intention

                if (transientSickness.getFirstDayPart() == PartOfDay.ALL_DAY &&
                        transientSickness.getLastDayPart() == PartOfDay.PM) {
                    probableFullDay = true;
                }

                if (probableFullDay) {

                    JOptionPane.showMessageDialog(this,
                            "From the part-of-day dropdowns, it appears that this is a full\n" +
                            "day of sickness; the dropdowns have been modified accordingly.\n" +
                            "If this interpretation is correct then \"Save\" again.",
                            "Save Sickness Report",
                            JOptionPane.ERROR_MESSAGE);

                    transientSickness.setFirstDayPart(PartOfDay.ALL_DAY);
                    transientSickness.setLastDayPart(PartOfDay.ALL_DAY);
                    
                } else {
                    JOptionPane.showMessageDialog(this,
                            "The part-of-day dropdowns do not seem to make sense",
                            "Save Sickness Report",
                            JOptionPane.ERROR_MESSAGE);
                }

                return false;
            }

        } else {

            if (negativeSpan) {
                JOptionPane.showMessageDialog(this,
                        "The start date must be before or equal to the end date",
                        "Save Sickness Report",
                        JOptionPane.ERROR_MESSAGE);
                return false;
            }

            if (transientSickness.getFirstDayPart() == PartOfDay.AM) {
                JOptionPane.showMessageDialog(this,
                        "The sickness report must start with either a\n" +
                        "full day (ALL_DAY) or just an afternoon (PM).",
                        "Save Sickness Report",
                        JOptionPane.ERROR_MESSAGE);
                return false;
            }

            if (transientSickness.getLastDayPart() == PartOfDay.PM) {
                JOptionPane.showMessageDialog(this,
                        "The sickness report must end with either a\n" +
                        "full day (ALL_DAY) or just a morining (AM).",
                        "Save Sickness Report",
                        JOptionPane.ERROR_MESSAGE);
                return false;
            }
        }

        // One last check to see if the holiday clashes with any others

        if (!SicknessCalculations.validateReport(transientSickness)) {
            JOptionPane.showMessageDialog(this,
                    "Sickness clashes with an existing report",
                    "Save Sickness Report",
                    JOptionPane.ERROR_MESSAGE);
            return false;
        }

        return true;
    }

    @Action
    public void cancelClicked() {
        setSaveSelected(false);
        setVisible(false);
    }

    @Action
    public void saveClicked() {

        if (!validateSicknessReport()) {
            return;
        }
        
        // Transfer transient values to persistent ones

        persistentSickness.copy(transientSickness);
        
        setSaveSelected(true);
        setVisible(false);
    }

    private void calculateSicknessSpend() {

        if (transientSickness != null &&
                transientSickness.getEmployeeId() != null &&
                !transientSickness.getTakenFromFlexi()) {

            DaisyChainUtilities.cleanDate(
                    transientSickness.getFirstDayOfSickness());
            DaisyChainUtilities.cleanDate(
                    transientSickness.getLastDayOfSickness());

            transientSickness.setHoursLost(sicknessCalculations.
                    getSicknessSpend(entityManager, transientSickness, null));
            
        } else {
            transientSickness.setHoursLost((double)0);
        }
    }

    public void propertyChange(PropertyChangeEvent evt) {
        calculateSicknessSpend();
    }

    @Action
    public void explainClicked() {

        if (transientSickness.getHoursLost() != null &&
                transientSickness.getHoursLost() > 0) {

            // Recalculate the holidays (with an expalantion)
            sicknessCalculations.getSicknessSpend(
                    entityManager, transientSickness, explanation);

            // Dump the explanation to our dialog box
            InformationDialog.showInformation(this,
                    "Holiday Calculation", explanation.getExplanation());
        }
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField administrator;
    private javax.swing.JTextField administratorComment;
    private javax.swing.JLabel administratorCommentLabel;
    private javax.swing.JLabel administratorLabel;
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JButton cancelButton;
    private TimeRecording.widgets.DateConverter dateConverter;
    private javax.swing.JComboBox employee;
    private javax.swing.JTextField employeeComment;
    private javax.swing.JLabel employeeCommentLabel;
    private javax.swing.JLabel employeeLabel;
    private javax.persistence.EntityManager entityManager;
    private javax.swing.JButton explainButton;
    private javax.swing.JComboBox firstDayPartCombo;
    private com.toedter.calendar.JDateChooser fromDate;
    private javax.swing.JCheckBox fromFlexiCheck;
    private javax.swing.JLabel fromLabel;
    private javax.swing.JFormattedTextField hoursLost;
    private javax.swing.JLabel hoursLostLabel;
    private javax.swing.JComboBox lastDayPartCombo;
    private javax.swing.JButton saveButton;
    private javax.swing.JPanel sicknessReportDetails;
    private TimeRecording.enums.SicknessReportStatusConverter sicknessReportStatusConverter;
    private javax.swing.JTextField status;
    private javax.swing.JLabel statusLabel;
    private com.toedter.calendar.JDateChooser toDate;
    private javax.swing.JLabel toLabel;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables

    private SicknessReportDialog myParent;
}
